Skip to content

feat(ts-sdk): Knowledge Graph client layer#97

Open
adnanrhussain wants to merge 7 commits into
mainfrom
ahussain/kg-client
Open

feat(ts-sdk): Knowledge Graph client layer#97
adnanrhussain wants to merge 7 commits into
mainfrom
ahussain/kg-client

Conversation

@adnanrhussain

@adnanrhussain adnanrhussain commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a typed HTTP client for the Learning Commons Knowledge Graph API. Infrastructure used by the Math Standards Alignment Evaluator (PR #91), kept as a separate PR so it can be reviewed independently.

  • KnowledgeGraphClient — single class that handles all KG HTTP calls with concurrency limiting (p-limit), promise caching (evict-on-reject so transient 429/503 errors are retryable), 30s timeout, and cursor-based pagination for learning components
  • KnowledgeGraphError — typed error for KG HTTP failures, exported from SDK root
  • platformApiKey added to BaseEvaluatorConfig for any evaluator that needs KG access
  • kg-api.d.ts generated from the official spec at docs.learningcommons.org/api-reference/knowledge-graph-api/openapi.yaml via npm run generate:kg-types

PR #91 depends on this

ahussain/math-standards-alignment (PR #91) must be merged after this one.

Test plan

  • npm test -- --run tests/unit/knowledge-graph — 19 tests pass
  • npx tsc --noEmit — 0 errors
  • npm run lint — 0 errors

Adds a typed HTTP client for the Learning Commons Knowledge Graph API,
used as infrastructure by the Math Standards Alignment Evaluator.

- KnowledgeGraphApiRepository — fetches standards and learning
  components via the KG REST API with cursor-based pagination,
  30s timeout, and correct MP standard filtering by normalizedStatementType
- KnowledgeGraphClient — concurrency-limited wrapper with promise
  caching (evicts on rejection so transient errors are retryable)
- KnowledgeGraphError — typed error for KG HTTP failures
- platformApiKey added to BaseEvaluatorConfig
- kg-api.d.ts generated from official spec at
  docs.learningcommons.org/api-reference/knowledge-graph-api/openapi.yaml
  via npm run generate:kg-types (openapi-typescript devDep)
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.33333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
sdks/typescript/src/knowledge-graph/client.ts 97.22% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Removes the KnowledgeGraphApiRepository/StandardsRepository abstraction layer.
KnowledgeGraphClient now handles HTTP calls directly alongside its caching
and concurrency logic — one class, one responsibility.

- repository.ts removed; HTTP logic moved into client.ts private methods
- StandardsRepository interface removed — no longer needed without the
  JSON repository variant
- Tests consolidated into client.test.ts covering all HTTP paths,
  caching eviction, pagination, and error mapping

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a TypeScript Knowledge Graph (KG) client layer to the SDK to support evaluators that need to fetch academic standards and learning components from the Learning Commons KG REST API.

Changes:

  • Introduces KnowledgeGraphClient with concurrency limiting, promise caching, and KG HTTP error handling.
  • Adds Knowledge Graph-specific types/utilities (AcademicStandard, LearningComponent, StandardInfo, parseGradeFromStandard) and generated OpenAPI typings (kg-api.d.ts).
  • Extends SDK configuration/error surface with platformApiKey on BaseEvaluatorConfig and KnowledgeGraphError exported from the SDK root.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
sdks/typescript/src/knowledge-graph/client.ts Implements KG HTTP fetch wrapper, caching, concurrency limiting, and KG query helpers.
sdks/typescript/src/knowledge-graph/types.ts Defines KG-facing domain types and grade parsing helper.
sdks/typescript/src/knowledge-graph/index.ts Barrel exports for KG client/types.
sdks/typescript/src/knowledge-graph/README.md Documents the KG client module and regeneration of generated types.
sdks/typescript/src/knowledge-graph/kg-api.d.ts Generated OpenAPI TypeScript types for KG API.
sdks/typescript/src/errors.ts Adds KnowledgeGraphError.
sdks/typescript/src/index.ts Exports KnowledgeGraphError from SDK root.
sdks/typescript/src/evaluators/base.ts Adds platformApiKey to base evaluator config.
sdks/typescript/tests/unit/knowledge-graph/client.test.ts Adds unit tests for KG client behavior and error handling.
sdks/typescript/package.json Adds generate:kg-types script and openapi-typescript dev dependency.
sdks/typescript/package-lock.json Lockfile updates reflecting dependency additions/adjustments.
Files not reviewed (1)
  • sdks/typescript/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sdks/typescript/src/knowledge-graph/client.ts
Comment thread sdks/typescript/src/index.ts
Comment thread sdks/typescript/src/errors.ts
Comment thread sdks/typescript/src/knowledge-graph/README.md Outdated
…inated

Adds the same hasMore guard as getLearningComponents — if limit=500
is ever insufficient for a grade, callers get an explicit error rather
than a silent truncation.
@adnanrhussain adnanrhussain requested review from a team, czi-fsisenda and georgemelvin June 10, 2026 04:09
The API confirmed it never returns 'Mathematical Practice' as a
normalizedStatementType for Mathematics subject queries — the URL
constraint normalizedStatementType=Standard already handles filtering.
The client-side filter was dead code based on a wrong assumption.

README stripped to bare minimum.
API confirmed HS standards are indexed under grades 9-12, not 'HS'.
parseGradeFromStandard now throws for HS-prefixed codes — callers
pass the explicit grade (9/10/11/12) when evaluating HS standards.
The evaluator requires callers to pass grade explicitly on every call.
Parsing grade from a statementCode prefix was ambiguous (HS codes span
4 grade years) and is no longer needed.
adnanrhussain added a commit that referenced this pull request Jun 10, 2026
Evaluates whether assessment questions align to CCSS math standards
by checking alignment at the learning-component level via the LC
Knowledge Graph API (see PR #97 for the KG client layer).

Three evaluation methods:
- evaluate(question, grade, statementCode) — single pair, primitive
- evaluateQuestionBank(questions[], statementCodes[]) — M×N cross-product
  with optional coarse filter (useCoarseFilter: true)
- evaluateByGrade(questions[], grade) — grade-level discovery wrapper

Model, temperature, supported grades, and max question length all
read from config.json / input_schema.json. platformApiKey doubles as
partnerKey for telemetry when not set separately.

@czi-fsisenda czi-fsisenda left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! 🙌

throw new AuthenticationError(`Knowledge Graph authentication failed: ${body}`, response.status);
}
if (response.status === 429) {
throw new RateLimitError(`Knowledge Graph rate limit exceeded: ${body}`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Is this retryable?

Comment on lines +64 to +65
private readonly standardInfoCache = new Map<string, Promise<StandardInfo>>();
private readonly lcCache = new Map<string, Promise<LearningComponent[]>>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have caching! Nice!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] AI says these are unbounded. Valid concern. But I think we can fit all the data these have in memory, right?

private readonly lcCache = new Map<string, Promise<LearningComponent[]>>();

constructor(apiKey: string, concurrency = 20) {
this.apiKey = apiKey;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] validate not empty.
I think you check the config elsewhere for this, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] add to .gitattributes as generated

LearningComponent now exposes the KG system identifier alongside
description. Used by the evaluator to verify model responses map
to the correct learning component — eliminating silent mismatches.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants